/*
 * @Description: USB_MT3Y协议解析控制
 * @Version: 0.1
 * @Autor: 宣某
 * @Date: 2020-08-09 19:09:35
 * @FilePath: \MT500-CURRENT-00\System\Protocol\USB_Protocol.c
 * @LastEditors: 许振富(jia)
 * @LastEditTime: 2022-06-29 17:00:57
 */
#include "Protocol.h"
#include "string.h"
#include "usb_lib.h"

#include "../ASM_Delay/ASM_Delay.h"

//不同协议下的最大包长,为0表示MT3Y带3协议，为1表示MT3Y不带3协议
const unsigned char MT3Y_Pack_Num[2] = {254,255};

__KeyBorad_LED_Sta KeyBorad_LED_Sta;

void USB_USB_Protocol_Init(void);//协议栈初始化
void USB_Protocol_Reset(void);//复位协议栈
void USB_Protocol_Rx_Handler(void);//接收数据处理函数
void USB_Protocol_Tx_Handler(unsigned short _sta, unsigned char *_buf, unsigned short _length);//发送数据处理函数
void USB_Protocol_ERR_CallBack(unsigned char _err);//接收错误回调
void USB_Protocol_Succeed_CallBack(void);//接收成功回调

__usb_protocol USB_Protocol = 
{
	.Init = USB_USB_Protocol_Init,
	.Reset = USB_Protocol_Reset,
	.Rx_Handler = USB_Protocol_Rx_Handler,
	.Tx_Handler = USB_Protocol_Tx_Handler,
	.ERR_CallBack = USB_Protocol_ERR_CallBack,
	.Succeed_CallBack = USB_Protocol_Succeed_CallBack,
	.Rx_Buffer = &Protocol_Rx_Buffer,
    .Tx_Buffer = &Protocol_Tx_Buffer
	
};

/**
 * @description: 设置协议模式,0表示MT3Y带3协议，1表示MT3Y不带3协议
 * @param {*}
 * @return {*}
 * @author: 宣某
 */
static void USB_Protocol_Select_Mode(unsigned char _mode)
{
//    if (USB_Protocol.Flag.Set_Mode_Flag == 0)
//    {
        if (_mode >= 0x30)
            USB_Protocol.Flag.Mode = _mode; //Mt3Y拆分模式
        else
            USB_Protocol.Flag.Mode = _mode; //Mt3Y合并模式
//    }
}
/**
 * @description: 初始化USBHID接收协议栈
 * @param {type} 
 * @return {type} 
 * @author: 宣某
 */
void USB_USB_Protocol_Init(void)
{
    *(unsigned short *)&USB_Protocol = 0;
    // USB_Protocol.Recevie_Bytes.Buffer = report_buf;
//    USB_Protocol.Rx_Buffer = &Protocol_Rx_Buffer;
//    USB_Protocol.Tx_Buffer = &Protocol_Tx_Buffer;
}
/**
 * @description: 复位USBHID接收协议栈
 * @param {type} 
 * @return {type} 
 * @author: 宣某
 */
void USB_Protocol_Reset(void)
{
    *(unsigned short *)&USB_Protocol &= 0x000c; //复位协议栈状态,除协议模式与协议模式设置位
    USB_Protocol.Recevie_Bytes.All_Number = 0;  //复位数据包字节长度
    USB_Protocol.Recevie_Bytes.Count = 0;       //复位接收数据包字节数
    USB_Protocol.LRC = 0;                       //复位LRC寄存器
}
/**
 * @description: 拆分接收数据时为长包的处理函数
 * @param {type} 
 * @return {type} 
 * @author: 宣某
 */
static unsigned char _Isolate_Protocol_LongMessage_Handler(void)
{
    unsigned char *temp;
    unsigned short each = 0;
    unsigned char LRC_temp = 0;
    //计算数据域全长
    Protocol_Rx_Buffer.Length -= 2;//去除命令域与LRC域
    Protocol_Rx_Buffer.Length *= 2;
    //去除拆分协议添加的0x30
    for (; each < Protocol_Rx_Buffer.Length; each++)
        Protocol_Rx_Buffer.Data[each] ^= 0x30;
    //计算处理完成后数据域的实际长度
    Protocol_Rx_Buffer.Length /= 2;
    //获取数据域首地址
    temp = Protocol_Rx_Buffer.Data;
    //开始处理整个数据域
    for (each = 0; each < Protocol_Rx_Buffer.Length; each++)
    {
        temp[each] = temp[each * 2] << 4;//合成高四位
        temp[each] |= temp[each * 2 + 1];//合成低四位
        USB_Protocol.LRC ^= temp[each];//计算LRC
    }
    //获取数据包中携带的LRC
    LRC_temp = temp[Protocol_Rx_Buffer.Length * 2] << 4;
    LRC_temp |= temp[Protocol_Rx_Buffer.Length * 2 + 1] & 0x0F;
	Protocol_Rx_Buffer.Length += 2;
    //比较数据包中的LRC与计算的LRC
    if (LRC_temp == USB_Protocol.LRC)
        return 0;//匹配
    return 1;//不匹配
}
/**
 * @description: 处理合并接收的长包数据
 * @param {*}
 * @return {*}
 * @author: 宣某
 */
static unsigned char _Combine_Protocol_LongMessage_Handler(void)
{
    unsigned char *temp;
    unsigned short each = 0;
    unsigned char LRC_temp = 0;
    //计算数据域全长
    Protocol_Rx_Buffer.Length -= 2; //去除命令域与LRC域
    //获取数据域首地址
    temp = Protocol_Rx_Buffer.Data;
    //开始处理整个数据域
    for (each = 0; each < Protocol_Rx_Buffer.Length; each++)
    {
        USB_Protocol.LRC ^= temp[each]; //计算LRC
    }
    //获取数据包中携带的LRC
    LRC_temp = temp[Protocol_Rx_Buffer.Length];
	Protocol_Rx_Buffer.Length += 2;
    //比较数据包中的LRC与计算的LRC
    if (LRC_temp == USB_Protocol.LRC)
        return 0;//匹配
    return 1;//不匹配
}
/**
 * @description: 合并接收USB下发数据
 * @param {*}
 * @return {*}
 * @author: 宣某
 */
static void Combine_Report_Handler(void)
{
    unsigned short PR_each;
    unsigned char *Rx_Buf_temp;
    unsigned char *Protocol_Buf_Temp;
    unsigned char LRC_temp;
    //判断是否为非长包标志
    if (USB_Protocol.Flag.Long_Report_Flag == 0)
    {
        //若是非长包,那显然这是数据的第一包        
        Rx_Buf_temp = USB_Protocol.Recevie_Bytes.Buffer;
		//第一包却没有包头,那就太扯了
        if (Rx_Buf_temp[0] != 0x06 &&
            Rx_Buf_temp[1] != 0x02)
            return;
        //获取本次通讯数据长度
        Protocol_Rx_Buffer.Length = Rx_Buf_temp[3];
        Protocol_Rx_Buffer.Length |= Rx_Buf_temp[2]<<8;
        //获取本次通讯数据命令
        Protocol_Rx_Buffer.Cmd = Rx_Buf_temp[5];
        Protocol_Rx_Buffer.Cmd |= Rx_Buf_temp[4]<<8;
        //计算命令部分的LRC
        USB_Protocol.LRC = Protocol_Rx_Buffer.Cmd >> 8;
        USB_Protocol.LRC ^= Protocol_Rx_Buffer.Cmd & 0xFF;
        //本次为单包通讯,249+5+1 == 255,最大单包
        if (Protocol_Rx_Buffer.Length <= 249)
        {
            //获取USB缓冲的地址
            Rx_Buf_temp = &USB_Protocol.Recevie_Bytes.Buffer[6];
            //获取协议数据域缓冲区的地址
            Protocol_Buf_Temp = Protocol_Rx_Buffer.Data;
            //计算数据的CRC,并处理数据域的数据
            for (PR_each = 0; PR_each < (Protocol_Rx_Buffer.Length-2); PR_each++)
            {
                //写入数据
                *Protocol_Buf_Temp = *(Rx_Buf_temp++);
                //计算LRC
                USB_Protocol.LRC ^= *(Protocol_Buf_Temp++);
            }
            LRC_temp = *(Rx_Buf_temp++);
            if (LRC_temp != USB_Protocol.LRC)
                USB_Protocol.ERR_CallBack(1);
            else
                USB_Protocol.Succeed_CallBack();
        }
        //本次为多包通讯
        else
        {
            //计算实际要传输的字节数量,减二是因为数据域的命令已被提取了
            USB_Protocol.Need_Bytes_Number = (Protocol_Rx_Buffer.Length - 2) + 3;
            //多包通讯置位
            USB_Protocol.Flag.Long_Report_Flag = 1;
            //获取USB缓冲的地址
            Rx_Buf_temp = &USB_Protocol.Recevie_Bytes.Buffer[6];
            //获取协议数据域缓冲区的地址
            Protocol_Buf_Temp = Protocol_Rx_Buffer.Data;
            //拷贝第一包中除命令外的其它数据
            memcpy(Protocol_Buf_Temp, Rx_Buf_temp, 249);
            //需要接收的字节数减去已经接受的字节数
            USB_Protocol.Need_Bytes_Number -= 249;
            //USB256字节缓冲区输出目标地址指针加载
            USB_Protocol.Recevie_Bytes.Out = Protocol_Buf_Temp + 249;
        }
    }
    //若为多包通讯
    else if (USB_Protocol.Flag.Long_Report_Flag)
    {
        //获取USB缓冲的地址
        Rx_Buf_temp = &USB_Protocol.Recevie_Bytes.Buffer[1];
        //若需要接收的数据大于254
        if (USB_Protocol.Need_Bytes_Number >= 254)
        {
            memcpy(USB_Protocol.Recevie_Bytes.Out, Rx_Buf_temp, 254);//接受这次的254个数据
            USB_Protocol.Need_Bytes_Number -= 254;//需要接收的数据减254
            USB_Protocol.Recevie_Bytes.Out += 254;//接受地址递增254
        }
        //若需要接收到的数据小于等于254
        else
        {
            //接受所有剩余数据
            memcpy(USB_Protocol.Recevie_Bytes.Out, Rx_Buf_temp, USB_Protocol.Need_Bytes_Number);
            //剩余数据归零
            USB_Protocol.Need_Bytes_Number = 0;
        }
        //若已经没有需要接受的数据了,那这次指令算是接收完了
        if (USB_Protocol.Need_Bytes_Number == 0)
        {
            //处理接收到的数据
            if (_Combine_Protocol_LongMessage_Handler())
                USB_Protocol.ERR_CallBack(1);//解析错误进入失败回调
            else
                USB_Protocol.Succeed_CallBack();//解析成功进入成功回调
        }
    }
}
//32Bit变量异或0x30303030
#define U32_XOR_30(x)	do{unsigned int temp = (x)^0x30303030;(x) = temp;}while(0)
//16Bit变量异或0x3030
#define U16_XOR_30(x)	do{unsigned short temp = (x)^0x3030;(x) = temp;}while(0)
//8Bit变量异或0x30
#define U8_XOR_30(x)	do{unsigned char temp = (x)^0x30;(x) = temp;}while(0)
//4Byte数据分别取低4Bit合成一个半字,高位在前
#define HALFBYTE_TO_U16(HalfByte, x)                    \
    do                                                  \
    {                                                   \
        (x) |= (*(unsigned char *)HalfByte) << 12;      \
        (x) |= (*(unsigned char *)(HalfByte + 1)) << 8; \
        (x) |= (*(unsigned char *)(HalfByte + 2)) << 4; \
        (x) |= (*(unsigned char *)(HalfByte + 3));      \
    } while (0);
/**
 * @description: 拆分接收USB下发数据
 * @param {*}
 * @return {*}
 * @author: 宣某
 */
static void Isolate_Report_Handler(void)
{
    unsigned short PR_each;
    unsigned char *Rx_Buf_temp;
    unsigned char *Protocol_Buf_Temp;
    unsigned char LRC_temp;

    //判断是否为非长包标志
    if (USB_Protocol.Flag.Long_Report_Flag == 0)
    {
        //若是非长包,那显然这是数据的第一包        
        Rx_Buf_temp = USB_Protocol.Recevie_Bytes.Buffer;
		//第一包却没有包头,那就太扯了
        if (Rx_Buf_temp[0] != 0x06 &&
            Rx_Buf_temp[1] != 0x02)
            return;
        //获取本次通讯数据长度
        Protocol_Rx_Buffer.Length = 0;
		U32_XOR_30((*(unsigned long *)(Rx_Buf_temp+2)));
        HALFBYTE_TO_U16(&Rx_Buf_temp[2],Protocol_Rx_Buffer.Length);
        //获取本次通讯数据命令
        Protocol_Rx_Buffer.Cmd = 0;
        U32_XOR_30((*(unsigned long *)(Rx_Buf_temp+6)));
		HALFBYTE_TO_U16(&Rx_Buf_temp[6],Protocol_Rx_Buffer.Cmd);
        //计算命令部分的LRC
        USB_Protocol.LRC = Protocol_Rx_Buffer.Cmd >> 8;
        USB_Protocol.LRC ^= Protocol_Rx_Buffer.Cmd & 0xFF;
        //本次为单包通讯,123*2+8+1 == 255,最大单包
        if (Protocol_Rx_Buffer.Length <= 123)
        {
			
            //获取USB缓冲的地址
            Rx_Buf_temp = &USB_Protocol.Recevie_Bytes.Buffer[10];
            //获取协议数据域缓冲区的地址
            Protocol_Buf_Temp = Protocol_Rx_Buffer.Data;
            //计算数据的CRC,并处理数据域的数据
            for (PR_each = 0; PR_each < Protocol_Rx_Buffer.Length-2; PR_each++)
            {
                //写入高四位
                *Protocol_Buf_Temp = *(Rx_Buf_temp++) << 4;
                //USB缓冲的地址++
                *Rx_Buf_temp ^= 0x30;
                //写入低四位
                *Protocol_Buf_Temp |= *(Rx_Buf_temp++);
                //计算LRC
                USB_Protocol.LRC ^= *(Protocol_Buf_Temp++);
            }
            LRC_temp = *(Rx_Buf_temp++) << 4;
            //格式化数据
            *Rx_Buf_temp ^= 0x30;
            //写入低四位
            LRC_temp |= *Rx_Buf_temp;
            //校验LRC
            if (LRC_temp != USB_Protocol.LRC)
                USB_Protocol.ERR_CallBack(1);   //失败
            else
                USB_Protocol.Succeed_CallBack();//成功
        }
        //本次为多包通讯
        else
        {
            //计算实际要传输的字节数量,减二是因为数据域的命令已被提取了
            USB_Protocol.Need_Bytes_Number = (Protocol_Rx_Buffer.Length - 2) * 2 + 3;
            //多包通讯置位
            USB_Protocol.Flag.Long_Report_Flag = 1;
            //获取USB缓冲的地址
            Rx_Buf_temp = &USB_Protocol.Recevie_Bytes.Buffer[10];
            //获取协议数据域缓冲区的地址
            Protocol_Buf_Temp = Protocol_Rx_Buffer.Data;
            //拷贝第一包中除命令外的其它数据
            memcpy(Protocol_Buf_Temp, Rx_Buf_temp, 245);
            //需要接收的字节数减去已经接受的字节数
            USB_Protocol.Need_Bytes_Number -= 245;
            //USB256字节缓冲区输出目标地址指针加载
            USB_Protocol.Recevie_Bytes.Out = Protocol_Buf_Temp + 245;
        }
    }
    //若为拆分多包通讯
    else if (USB_Protocol.Flag.Long_Report_Flag)
    {
		if(Protocol_Rx_Buffer.Length == 0x009F)
				__nop();
        //获取USB缓冲的地址
        Rx_Buf_temp = &USB_Protocol.Recevie_Bytes.Buffer[1];
        //若需要接收的数据大于254
        if (USB_Protocol.Need_Bytes_Number >= 254)
        {
            memcpy(USB_Protocol.Recevie_Bytes.Out, Rx_Buf_temp, 254);//接受这次的254个数据
            USB_Protocol.Need_Bytes_Number -= 254;//需要接收的数据减254
            USB_Protocol.Recevie_Bytes.Out += 254;//接受地址递增254
        }
        //若需要接收到的数据小于等于254
        else
        {
            //接受所有剩余数据
            memcpy(USB_Protocol.Recevie_Bytes.Out, Rx_Buf_temp, USB_Protocol.Need_Bytes_Number);
            //剩余数据归零
            USB_Protocol.Need_Bytes_Number = 0;
        }
        //若已经没有需要接受的数据了,那这次指令算是接收完了
        if (USB_Protocol.Need_Bytes_Number == 0)
        {
            //处理接收到的数据
            if (_Isolate_Protocol_LongMessage_Handler())
                USB_Protocol.ERR_CallBack(1);//解析错误进入失败回调
            else
                USB_Protocol.Succeed_CallBack();//解析成功进入成功回调
        }
    }
}
/**
 * @description: 接受数据处理函数
 * @param {type} 
 * @return {type} 
 * @author: 宣某
 */	
void USB_Protocol_Rx_Handler(void)
{
	unsigned char * temp = USB_Protocol.Recevie_Bytes.Buffer;
	if (temp[0] == 0x06 && temp[1] == 0x02)
	{
		if (((temp[2] & 0xf0) == 0x30) && ((temp[3] & 0xf0) == 0x30) && ((temp[4] & 0xf0) == 0x30) && ((temp[5] & 0xf0) == 0x30))
		{
//			tonxun_xieyi = 0; //为0表示MT3Y带3协议，为1表示MT3Y不带3协议；
			USB_Protocol_Select_Mode(0);
		}
		else
		{
//			tonxun_xieyi = 1; //为0表示MT3Y带3协议，为1表示MT3Y不带3协议；
			USB_Protocol_Select_Mode(1);
		}
	}
    
	if(USB_Protocol.Flag.Mode == 0) //Mt3Y拆分模式)
		Isolate_Report_Handler();
	else if(USB_Protocol.Flag.Mode == 1) //Mt3Y合并模式
        Combine_Report_Handler();
}
/**
 * @description: 匹配指令失败回调
 * @param {type} _err:错误类型
 * @return {type} 
 * @author: 宣某
 */
void USB_Protocol_ERR_CallBack(unsigned char _err)
{
    unsigned char temp[2] = {0xFF, 0xFF};
    USB_Protocol.Flag.Long_Report_Flag = 0;
//    USB_Protocol.Tx_Handler(0x00, temp, 2);
    switch (_err)
    {
    case 0:
        break;
    case 1:
        break;
    default:
        break;
    }
}
/**
 * @description: 成功匹配指令回调
 * @param {type} 
 * @return {type} 
 * @author: 宣某
 */
void USB_Protocol_Succeed_CallBack(void)
{
    USB_Protocol.Reset();   //复位协议栈
    USB_Protocol.Flag.Command_Valid_Flag = 1;//成功匹配标志置一
}


//边界检查,换包就添加0x06的包头
#define TX_BOUNDARY_CHECK()                                                    \
    do                                                                         \
    {                                                                          \
        if (temp - Protocol_Tx_Buffer.Transmit_Buffer >= MT3Y_Pack_Num[USB_Protocol.Flag.Mode])             \
            if (((temp - Protocol_Tx_Buffer.Transmit_Buffer) % MT3Y_Pack_Num[USB_Protocol.Flag.Mode]) == 0) \
                *(temp++) = 0x06;                                              \
    } while (0)
/**
 * @description: 拆分协议向USB返回数据
 * @param {unsigned short} _sta:返回状态
 * @param {unsigned char*} _buf:返回数据
 * @param {unsigned short} _length:返回数据长度
 * @return {*}
 * @author: 宣某
 */
static void Isolate_Tx_Handler(unsigned short _sta, unsigned char *_buf, unsigned short _length)
{
    unsigned char *temp;
    unsigned char LRC_temp = 0;
    memset(USB_Protocol.Tx_Buffer->Transmit_Buffer, 0x30, sizeof(USB_Protocol.Tx_Buffer->Transmit_Buffer));
    temp = USB_Protocol.Tx_Buffer->Transmit_Buffer;

    //写入数据头
    *(temp++) = 0x06;
    *(temp++) = 0x02;
    //写入数据长度
    _length += 2;
    *(temp++) |= _length >> 12 & 0x0f;
    *(temp++) |= _length >> 8 & 0x0f;
    *(temp++) |= _length >> 4 & 0x0f;
    *(temp++) |= _length & 0x0f;
    //写入状态位
    *(temp++) |= _sta >> 12 & 0x0f;
    *(temp++) |= _sta >> 8 & 0x0f;
    *(temp++) |= _sta >> 4 & 0x0f;
    *(temp++) |= _sta & 0x0f;
    //计算LRC
    LRC_temp ^= _sta >> 8;
    LRC_temp ^= _sta & 0xFF;
    //循环写入数据
    _length -= 2;
    while (_length--)
    {
        *(temp++) |= *_buf >> 4;   //数据高四位
        TX_BOUNDARY_CHECK();       //分包边界检查
        *(temp++) |= *_buf & 0x0f; //数据高四位
        TX_BOUNDARY_CHECK();       //分包边界检查
        LRC_temp ^= *(_buf++);     //LRC计算
    }
    *(temp++) |= LRC_temp >> 4;   //LRC数据高四位
    TX_BOUNDARY_CHECK();          //分包边界检查
    *(temp++) |= LRC_temp & 0x0F; //LRC数据高四位
    TX_BOUNDARY_CHECK();          //分包边界检查
    *(temp++) = 0x03;             //数据尾
    //计算需要发送的数据长度
    USB_Protocol.Tx_Buffer->Length = temp - USB_Protocol.Tx_Buffer->Transmit_Buffer;
    //将需要发送的数据长度交给发送计数器
    USB_Protocol.Transmi_Bytes.Need_Transmit_Bytes = USB_Protocol.Tx_Buffer->Length;
    //将发送缓冲区首地址交给发送指针
	//Protocol_Tx_Buffer
    USB_Protocol.Transmi_Bytes.Out = USB_Protocol.Tx_Buffer->Transmit_Buffer;
//	USB_Protocol.Transmi_Bytes.Out = (void*)&Protocol_Tx_Buffer.Transmit_Buffer;
    //发送数据准备完成标志置一
    USB_Protocol.Flag.Transmit_State = 1;
}

/**
 * @description: 合并协议向USB返回数据
 * @param {unsigned short} _sta:返回状态
 * @param {unsigned char*} _buf:返回数据
 * @param {unsigned short} _length:返回数据长度
 * @return {*}
 * @author: 宣某
 */
static void Combine_Tx_Handler(unsigned short _sta, unsigned char *_buf, unsigned short _length)
{
    unsigned char *temp;
    unsigned char LRC_temp = 0;
    memset(USB_Protocol.Tx_Buffer->Transmit_Buffer, 0x00, sizeof(USB_Protocol.Tx_Buffer->Transmit_Buffer));
    temp = USB_Protocol.Tx_Buffer->Transmit_Buffer;
    //写入数据头
    *(temp++) = 0x06;
    *(temp++) = 0x02;
    //写入数据长度
    _length += 2;
    *(temp++) = _length >> 8 & 0xff;
    *(temp++) |= _length & 0xff;
    //写入状态位
    *(temp++) = _sta >> 8 & 0xff;
    *(temp++) |= _sta & 0xff;
    //计算LRC
    LRC_temp ^= _sta >> 8;
    LRC_temp ^= _sta & 0xFF;
    //循环写入数据
    _length -= 2;
    while (_length--)
    {
        *(temp++) |= *_buf;    //写入数据
		if(*_buf != 0)
			__nop();
        TX_BOUNDARY_CHECK();   //分包边界检查
        LRC_temp ^= *(_buf++); //LRC计算
    }
    *(temp++) |= LRC_temp; //LRC数据高四位
    TX_BOUNDARY_CHECK();   //分包边界检查
    *(temp++) = 0x03;      //数据尾
    //计算需要发送的数据长度
    USB_Protocol.Tx_Buffer->Length = temp - USB_Protocol.Tx_Buffer->Transmit_Buffer;
    //将需要发送的数据长度交给发送计数器
    USB_Protocol.Transmi_Bytes.Need_Transmit_Bytes = USB_Protocol.Tx_Buffer->Length;
    //将发送缓冲区首地址交给发送指针
    USB_Protocol.Transmi_Bytes.Out = USB_Protocol.Tx_Buffer->Transmit_Buffer;
    //发送数据准备完成标志置一
    USB_Protocol.Flag.Transmit_State = 1;
}



/**
 * @description: USB发送数据处理
 * @param {type} _sta:状态位 当为0xFFFF时协议取消状态位
 * @param {type} _buf:需要发送的数据首地址
 * @param {type} _length:需要发送的数据的长度(这个长度不需要包含状态位的长度)
 * @return {type} 
 * @author: 宣某
 */    
void USB_Protocol_Tx_Handler(unsigned short _sta, unsigned char *_buf, unsigned short _length)
{
	
	/* USB回报上位大包计数 */
extern uint32_t USB_LongReportPack;
/* USB数据接收处理中标志,处理中时不允许回报数据 */
extern  unsigned char Not_processed_flag;
/* 回报USB的总长度 */
extern volatile u32 data_length;
	if(USB_Protocol.Flag.Mode == 0) //Mt3Y拆分模式)
		Isolate_Tx_Handler(_sta,_buf,_length);
	else if(USB_Protocol.Flag.Mode == 1) //Mt3Y合并模式
        Combine_Tx_Handler(_sta,_buf,_length);

	data_length = USB_Protocol.Tx_Buffer->Length; //len*2+9;
	Not_processed_flag = 0;
	USB_LongReportPack = 0;
	ASM_DELAY_MS(1);	
	_SetEPTxStatus(ENDP0, EP_TX_VALID);
//	while(USB_Protocol.Flag.Transmit_State == 1)
//	{	
//		
//	}
}

volatile unsigned char ReplyTogether_temp[256] ;

__Key_Seqence_Typedef Key_Seqence[3] =
    {
        {3,
         "123"},
        {sizeof("C:\\Users\\22776\\Desktop\\software\\Beyond Compare\\BCompare.exe")-1,
         "C:\\Users\\22776\\Desktop\\software\\Beyond Compare\\BCompare.exe"},
        {2,
         "tc"}};

static unsigned char Other_Key_Buf = 0;

/**
 * @description: 检查输入数据是否为字母
 * @param {unsigned char} _Char
 * @return {*} 1:是 0:不是
 * @author: 许振富(jia)
 */
static unsigned char Cheack_Letter(unsigned char _Char)
{
	if(_Char >= 'a' && _Char <= 'z')
		return 1;
	if(_Char >= 'A' && _Char <= 'Z')
		return 1;
	return 0;
}
/**
 * @description: 检查电脑是否处于大写锁定模式 
 * @param {*}
 * @return {*} 1:锁定 0:未锁定
 * @author: 许振富(jia)
 */
static unsigned char Cheack_CapsLock(void)
{
	if(KeyBorad_LED_Sta.Caps_Lock)
		return 1;
	return 0;
}

/* 按下ctrl键 */
void KeyBorad_Ctrl_Down(void)
{
	u8 i, Buffer[8] = {01, 0, 0, 0, 0, 0, 0, 0};
    //按键按下
	UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
    SetEPTxValid(ENDP2);
    while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
        ;
}

void KeyBorad_Ctrl_Up(void)
{
	u8 i, Buffer[8] = {00, 0, 0, 0, 0, 0, 0, 0};
    //按键按下
	UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
    SetEPTxValid(ENDP2);
    while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
        ;
}

/* 单击Lock键 */
void KeyBorad_CapsLock_Click(void)
{
	u8 i, Buffer[8] = {00, 0, 0, 0, 0, 0, 0, 0};
	Buffer[2] = 0X39;
    //按键按下
	UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
    SetEPTxValid(ENDP2);
    while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
        ;
    for (i = 0; i < 8; i++)
        Buffer[i] = 0;
    //按键弹起
    UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
    SetEPTxValid(ENDP2);
    while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
        ;
	ASM_DELAY_MS(20);
}
/* 特殊按键按下 1:ctrl 2:shift 3:alt 4:gui */
void KeyBorad_Other_Key_Down(unsigned char _Key)
{
	switch(_Key)
	{
		/* ctrl */
		case(1):Other_Key_Buf |= 0x01;break;
		/* shift */
		case(2):Other_Key_Buf |= 0x02;break;
		/* alt */
		case(3):Other_Key_Buf |= 0x04;break;
		/* gui */
		case(4):Other_Key_Buf |= 0x08;break;
	}
}

/* 按键按下 */
void KeyBorad_Ascll_Key_Down(unsigned char _Key)
{
	unsigned char i, Buffer[8] = {Other_Key_Buf, 0, 0, 0, 0, 0, 0, 0};
	unsigned char chgchar[96] = {0x2c, 0x9e, 0xb4, 0xa0, 0xa1, 0xa2, 0xa4, 0x34, 0xa6, 0xa7, 0xa5, 0xae, 0x36, 0x2d, 0x37, 0x38, 0x27, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
								  0x24, 0x25, 0x26, 0xb3, 0x33, 0xb6, 0x2e, 0xb7, 0xb8, 0x9f, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
								  0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x2f, 0x31, 0x30, 0xa3, 0xad, 0x35, 0x04, 0x05, 0x06, 0x07,
								  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0xaf,
								  0xb1, 0xb0, 0xb5, 0x28};
	_Key = _Key - 32;
	Buffer[2] = chgchar[_Key];
    //按键按下
	UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
    SetEPTxValid(ENDP2);
    while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
        ;
}

/* 所有按键弹起 */
void KeyBorad_All_Key_Up(void)
{
	unsigned char i, Buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
	Other_Key_Buf = 0;
    //按键按下
	UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
    SetEPTxValid(ENDP2);
    while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
        ;
}
/**
 * @brief 模拟键盘输出一个字节
 * 
 * @param ch 
 */
void SendToKB(u8 ch)
{
	u8 i, Buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
	u8 chgchar[96] = {0x2c, 0x9e, 0xb4, 0xa0, 0xa1, 0xa2, 0xa4, 0x34, 0xa6, 0xa7, 0xa5, 0xae, 0x36, 0x2d, 0x37, 0x38, 0x27, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
					  0x24, 0x25, 0x26, 0xb3, 0x33, 0xb6, 0x2e, 0xb7, 0xb8, 0x9f, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
					  0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x2f, 0x31, 0x30, 0xa3, 0xad, 0x35, 0x04, 0x05, 0x06, 0x07,
					  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0xaf,
					  0xb1, 0xb0, 0xb5, 0x28};
	unsigned char _Char = ch;
	ch = ch - 32;
	/* 若要输入的是要按Shift才能输出的字符 */
	if ((chgchar[ch] & 0x80) != 0)
	{
		/* 填充Shift按下键值 */
		Buffer[0] = 0x02;
		/* 若电脑处于大写锁定状态 */
		if (Cheack_CapsLock() == 1)
		{
			/* 若本次输出的是字符,则清除Shift按下键值,因为电脑已经锁定大写了 */
			if (Cheack_Letter(_Char) == 1)
			{
				Buffer[0] = 0x00;
			}
		}
		else
		{
			/* 发送按下Shift的数据包 */
			UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
			SetEPTxValid(ENDP2);
			while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
				;
		}
		/* 计算实际键值 */
		chgchar[ch] = chgchar[ch] & 0x7f;

	} /* 若要输入的是不需要按Shift输出的字符 */
	else
	{
		/* 若电脑处于大写锁定状态 */
		if (Cheack_CapsLock() == 1)
		{
			/* 若本次输出的是字符 */
			if (Cheack_Letter(_Char) == 1)
			{
				/* 填充Shift按下键值 */
				Buffer[0] = 0x02;
				UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
				SetEPTxValid(ENDP2);
				while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
					;
			}
		}
	}
//	ASM_DELAY_MS(1);
	Buffer[2] = chgchar[ch];
	//按键按下
	UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
	SetEPTxValid(ENDP2);
	while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
		;
	for (i = 0; i < 8; i++)
		Buffer[i] = 0;
	//按键弹起
	UserToPMABufferCopy(Buffer, GetEPTxAddr(ENDP2), 8);
	SetEPTxValid(ENDP2);
	while (GetEPTxStatus((ENDP2 & 0x7F)) != EP_TX_NAK)
		;	
}
/**
 * @brief 模拟键盘输出字符串
 * 
 * @param _Str 字符串
 * @param _Len 字符串长度
 */
void SendKB_String(unsigned char* _Str,unsigned short _Len)
{
	unsigned short each = 0;
	/* 键盘默认Lock状态 */
	unsigned char KeyBorad_Lock_Flag = 0;

	/* 若电脑不处于大写锁定状态,就让它进去 */
	KeyBorad_Lock_Flag = Cheack_CapsLock();
	if (KeyBorad_Lock_Flag != 1)
		KeyBorad_CapsLock_Click();
	for(each = 0; each < _Len ;each++)
		SendToKB(_Str[each]);
	/* 若电脑不处于大写锁定状态,就让它出来 */
	if (KeyBorad_Lock_Flag == 0)
		KeyBorad_CapsLock_Click();
}

/**
 * @brief 模拟键盘输出字符串带换行
 * 
 * @param _Str 字符串
 * @param _Len 字符串长度
 */
void SendKB_Stringln(unsigned char* _Str,unsigned short _Len)
{
	unsigned short each = 0;
	/* 键盘默认Lock状态 */
	unsigned char KeyBorad_Lock_Flag = 0;

	/* 若电脑不处于大写锁定状态,就让它进去 */
	KeyBorad_Lock_Flag = Cheack_CapsLock();
	if (KeyBorad_Lock_Flag != 1)
		KeyBorad_CapsLock_Click();
	for(each = 0; each < _Len ;each++)
		SendToKB(_Str[each]);
	/* 若电脑不处于大写锁定状态,就让它出来 */
	if (KeyBorad_Lock_Flag == 0)
		KeyBorad_CapsLock_Click();
	SendToKB(127);
}
///**
// * @brief USB中断使能控制
// * 
// * @param _New_State 1:使能USB中断
// */
//void USB_Interrup_Cmd(unsigned char _New_State)
//{
//	NVIC_InitTypeDef NVIC_InitStructure; 
//	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//	
//	switch(_New_State)
//	{
//		case(0):NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;break;
//		case(1):NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;break;
//		default:break;
//	}
//	NVIC_Init(&NVIC_InitStructure);
//}
